package com.matrix.codeGeneration.ext;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;

import com.matrix.codeGeneration.convert.DefaultTypeHandle;
import com.matrix.codeGeneration.model.OutDataSource;
import com.matrix.codeGeneration.model.PropertyColumn;
import com.matrix.codeGeneration.model.TableClassModel;
import com.matrix.codeGeneration.plugin.ExcelImport;

/**
 * excel数据源
 * 
 * @author jiangyouyao
 *
 */
public class ExcelDataSource extends OutDataSource {
	// excel文件地址
	private String sourcePath;
	private String author;

	private String dbType;

	public ExcelDataSource() {
	}

	@Override
	public List<TableClassModel> convertToTableModel() {

		Map<String, List<List<Object>>> analysisExcel = new HashMap<>();
		// 源文件路径
		File sourceDir = new File(sourcePath);
		if (!sourceDir.isDirectory()) {
			new Exception("目标目录不存在");
		}
		File[] files = sourceDir.listFiles();
		if (files != null) {
			for (File file : files) {
				if (file.canRead()) {// 是否为一个可读文件
					String fileName = file.getName();
					// 检查扩展名称
					String extension = fileName.lastIndexOf(".") == -1 ? ""
							: fileName.substring(fileName.lastIndexOf(".") + 1);
					if (extension.equals("xls") || extension.equals("xlsx")) {
						System.out.println(fileName);
						// 读取excel文件的内容
						try {
							analysisExcel.putAll(ExcelImport.read2007ExcelAllShell(file, null, 6));
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				} else {
					new RuntimeException(file.getName() + "文件不可读");
				}
			}
		}
		List<TableClassModel> models = analysisExcel(analysisExcel);
		this.setTableClassModels(models);
		return this.getTableClassModels();
	}

	/**
	 * 解析excel文件中数据表信息
	 * 
	 * @param analysisExcel
	 * @return
	 */
	private List<TableClassModel> analysisExcel(Map<String, List<List<Object>>> analysisExcel) {
		List<TableClassModel> models = new ArrayList<>();
		Set<String> keys = analysisExcel.keySet();
		// 除了第一行，其他每一行代表一个字段，一个key是一个表
		for (String tableName : keys) {
			TableClassModel model = new TableClassModel();
			List<List<Object>> data = analysisExcel.get(tableName);
			// 设置数据表基本信息
			// 构建表名

			int nameIndex = tableName.indexOf("(");
			model.setTableMemo(tableName.substring(nameIndex+1, tableName.length()-1));
			model.setTableName(tableName.substring(0, nameIndex));
			// 设置类名和变量名称
			model.setClassName(getNameConvert().tableNameToClassName(model.getTableName()));
			model.setClassVariableName(getNameConvert().classNameToVariableName(model.getClassName()));

			// 遍历设置字段信息
			for (int i = 1; i < data.size(); i++) {
				List<Object> row = data.get(i);
				PropertyColumn p = new PropertyColumn();
				// 列名
				String columnName = (String) row.get(0);
				p.setColumn(columnName);
				// 属性名称
				p.setProperty(getNameConvert().columnToProperty(columnName));

				// 字段类型、长度
				String type = (String) row.get(2);
				p.setFullJdbcType(type);

				// jdbc类型设置
				int index = type.indexOf("(") > 0 ? type.indexOf("(") : type.length();

				p.setJdbcType(type.substring(0, index).trim().replaceAll("2", ""));
				System.out.println("jdbctype=" + p.getJdbcType());
				// 基本类型
				p.setClassType(DefaultTypeHandle.TypeMapping.get(dbType).get(p.getJdbcType()));

				String isAllowNull = (String) row.get(3);

				if (isAllowNull != null && isAllowNull.equals("N")) {
					isAllowNull = " NOT NULL ";
				} else {
					isAllowNull = "";
				}

				p.setIsAllowNull(isAllowNull);

				// 备注中 [表示界面显示字段] [表示必填字段*]
				String memo = (String) row.get(1);
				int begin = memo.indexOf("[");
				int end = memo.indexOf("]");

				if (begin > -1 && end - begin > 1) {
					// 显示到页面上的字段
					String subString1 = memo.substring(begin, end);
					boolean isNecessary = subString1.indexOf("*") > 0;
					if (isNecessary) {
						p.setShowName(memo.substring(begin + 1, end - 1));
					} else {
						p.setShowName(memo.substring(begin + 1, end));
					}
					p.setIsNecessary(isNecessary);
					p.setIsVisible(true);
					// 截取[符号前面的字段作为数据库的备注
					p.setMemo(memo.substring(0, begin));
				} else {
					p.setIsNecessary(false);
					p.setIsVisible(false);
					p.setMemo(memo);
				}
				// get，set方法名称
				p.setMethodName(getNameConvert().propertyToMethod(p.getProperty()));

				// 设置主键
				if (p.getMemo() != null && p.getMemo().equals("主键")) {
					p.setIsPrimaryKey(true);
					model.setPrimaryKey(p);
				} else {
					p.setIsPrimaryKey(false);
				}

				// 设置jsp编辑页面字段长度限制
				String columnLengthStr = row.get(6) == null ? null : (String) row.get(6);
				if (StringUtils.isNotBlank(columnLengthStr)) {
					// 从excel中读取的数字默认是double类型的，所以做如下处理去掉小数点
					Double columnLength = Double.parseDouble(columnLengthStr);
                    p.setColumnLength(columnLength.intValue()+"");
				}

				model.getMapping().add(p);
			}
			models.add(model);
		}
		System.out.println(analysisExcel);
		return models;
	}

	public String getSourcePath() {
		return sourcePath;
	}

	public void setDbType(String dbType) {
		this.dbType = dbType;
	}

	public void setSourcePath(String sourcePath) {
		this.sourcePath = sourcePath;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getAuthor() {
		return author;
	}

	public String getDbType() {
		return dbType;
	}

}
